import { supabase } from '@/lib/supabase'
import type { Database } from '@/types/database'
import type {
  CoupleProfile,
  User,
  Anniversary,
  Album,
  Photo,
  Message,
  DateRecord,
  Gift,
  WishItem,
} from '@/types/couple'

// 类型别名
type Tables = Database['public']['Tables']

// 用户服务
export const userService = {
  async create(user: Omit<User, 'id'>, authUserId?: string): Promise<User> {
    const { data, error } = await supabase
      .from('users')
      .insert({
        auth_user_id: authUserId || null,
        name: user.name,
        avatar: user.avatar,
        birthday: user.birthday,
        gender: user.gender,
        phone: user.phone || null,
        email: user.email || null,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapUserFromDB(data)
  },

  async getById(id: string): Promise<User | null> {
    const { data, error } = await supabase
      .from('users')
      .select('*')
      .eq('id', id)
      .single()

    if (error)
      return null
    return mapUserFromDB(data)
  },

  async getByAuthId(authId: string): Promise<User | null> {
    const { data, error } = await supabase
      .from('users')
      .select('*')
      .eq('auth_user_id', authId)
      .single()

    if (error)
      return null
    return mapUserFromDB(data)
  },

  async update(id: string, updates: Partial<User>): Promise<User> {
    const { data, error } = await supabase
      .from('users')
      .update({
        name: updates.name,
        avatar: updates.avatar,
        birthday: updates.birthday,
        gender: updates.gender,
        phone: updates.phone || null,
        email: updates.email || null,
        updated_at: new Date().toISOString(),
      })
      .eq('id', id)
      .select()
      .single()

    if (error)
      throw error
    return mapUserFromDB(data)
  },
}

// A type for creating a new profile where users don't have IDs yet
export type NewCoupleProfilePayload = Omit<CoupleProfile, 'id' | 'createdAt' | 'updatedAt' | 'user1' | 'user2'> & {
  user1: Omit<User, 'id'>
  user2: Omit<User, 'id'>
}

// 情侣档案服务
export const coupleService = {
  async create(profile: NewCoupleProfilePayload): Promise<CoupleProfile> {
    // 首先创建或获取用户
    const user1 = await userService.create(profile.user1)
    const user2 = await userService.create(profile.user2)

    const { data, error } = await supabase
      .from('couple_profiles')
      .insert({
        user1_id: user1.id,
        user2_id: user2.id,
        relationship_start: profile.relationshipStart,
        status: profile.status,
        anniversary: profile.anniversary || null,
        story: profile.story || null,
        cover_image: profile.coverImage || null,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapCoupleProfileFromDB(data, user1, user2)
  },

  async getById(id: string): Promise<CoupleProfile | null> {
    const { data, error } = await supabase
      .from('couple_profiles')
      .select(`
        *,
        user1:users!user1_id(*),
        user2:users!user2_id(*)
      `)
      .eq('id', id)
      .single()

    if (error)
      return null
    const u1 = (data as any).user1
    const u2 = (data as any).user2
    const user1 = mapUserFromDB(Array.isArray(u1) ? u1[0] : u1)
    const user2 = mapUserFromDB(Array.isArray(u2) ? u2[0] : u2)
    return mapCoupleProfileFromDB(data, user1, user2)
  },

  async update(id: string, updates: Partial<CoupleProfile>): Promise<CoupleProfile> {
    const { data, error } = await supabase
      .from('couple_profiles')
      .update({
        relationship_start: updates.relationshipStart,
        status: updates.status,
        anniversary: updates.anniversary || null,
        story: updates.story || null,
        cover_image: updates.coverImage || null,
        updated_at: new Date().toISOString(),
      })
      .eq('id', id)
      .select(`
        *,
        user1:users!user1_id(*),
        user2:users!user2_id(*)
      `)
      .single()

    if (error)
      throw error
    const u1 = (data as any).user1
    const u2 = (data as any).user2
    const user1 = mapUserFromDB(Array.isArray(u1) ? u1[0] : u1)
    const user2 = mapUserFromDB(Array.isArray(u2) ? u2[0] : u2)
    return mapCoupleProfileFromDB(data, user1, user2)
  },
}

// 消息服务
export const messageService = {
  async create(coupleId: string, message: Omit<Message, 'id' | 'createdAt'>): Promise<Message> {
    const { data, error } = await supabase
      .from('messages')
      .insert({
        couple_id: coupleId,
        content: message.content,
        type: message.type,
        sender_id: message.sender,
        receiver_id: message.receiver,
        is_read: message.isRead,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapMessageFromDB(data)
  },

  async getByCouple(coupleId: string): Promise<Message[]> {
    const { data, error } = await supabase
      .from('messages')
      .select('*')
      .eq('couple_id', coupleId)
      .order('created_at', { ascending: false })

    if (error)
      throw error
    return data.map(mapMessageFromDB)
  },

  async markAsRead(id: string): Promise<void> {
    const { error } = await supabase
      .from('messages')
      .update({ is_read: true })
      .eq('id', id)

    if (error)
      throw error
  },
}

// 纪念日服务
export const anniversaryService = {
  async create(coupleId: string, anniversary: Omit<Anniversary, 'id' | 'createdAt'>): Promise<Anniversary> {
    const { data, error } = await supabase
      .from('anniversaries')
      .insert({
        couple_id: coupleId,
        title: anniversary.title,
        date: anniversary.date,
        type: anniversary.type,
        description: anniversary.description || null,
        is_recurring: anniversary.isRecurring,
        reminder_days: anniversary.reminderDays || null,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapAnniversaryFromDB(data)
  },

  async getByCouple(coupleId: string): Promise<Anniversary[]> {
    const { data, error } = await supabase
      .from('anniversaries')
      .select('*')
      .eq('couple_id', coupleId)
      .order('date', { ascending: true })

    if (error)
      throw error
    return data.map(mapAnniversaryFromDB)
  },

  async update(id: string, updates: Partial<Anniversary>): Promise<Anniversary> {
    const { data, error } = await supabase
      .from('anniversaries')
      .update({
        title: updates.title,
        date: updates.date,
        type: updates.type,
        description: updates.description || null,
        is_recurring: updates.isRecurring,
        reminder_days: updates.reminderDays || null,
      })
      .eq('id', id)
      .select()
      .single()

    if (error)
      throw error
    return mapAnniversaryFromDB(data)
  },

  async delete(id: string): Promise<void> {
    const { error } = await supabase
      .from('anniversaries')
      .delete()
      .eq('id', id)

    if (error)
      throw error
  },
}

// 约会记录服务
export const dateRecordService = {
  async create(coupleId: string, record: Omit<DateRecord, 'id' | 'createdAt'>): Promise<DateRecord> {
    const { data, error } = await supabase
      .from('date_records')
      .insert({
        couple_id: coupleId,
        title: record.title,
        date: record.date,
        location: record.location,
        description: record.description || null,
        photos: record.photos,
        mood: record.mood,
        cost: record.cost || null,
        weather: record.weather || null,
        tags: record.tags,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapDateRecordFromDB(data)
  },

  async getByCouple(coupleId: string): Promise<DateRecord[]> {
    const { data, error } = await supabase
      .from('date_records')
      .select('*')
      .eq('couple_id', coupleId)
      .order('date', { ascending: false })

    if (error)
      throw error
    return data.map(mapDateRecordFromDB)
  },

  async update(id: string, updates: Partial<DateRecord>): Promise<DateRecord> {
    const { data, error } = await supabase
      .from('date_records')
      .update({
        title: updates.title,
        date: updates.date,
        location: updates.location,
        description: updates.description || null,
        photos: updates.photos,
        mood: updates.mood,
        cost: updates.cost || null,
        weather: updates.weather || null,
        tags: updates.tags,
      })
      .eq('id', id)
      .select()
      .single()

    if (error)
      throw error
    return mapDateRecordFromDB(data)
  },

  async delete(id: string): Promise<void> {
    const { error } = await supabase
      .from('date_records')
      .delete()
      .eq('id', id)

    if (error)
      throw error
  },
}

// 数据映射函数
function mapUserFromDB(data: Tables['users']['Row']): User {
  return {
    id: data.id,
    // auth_user_id is not part of the client-side User model
    name: data.name,
    avatar: data.avatar,
    birthday: data.birthday,
    gender: data.gender,
    phone: data.phone || undefined,
    email: data.email || undefined,
  }
}

function mapCoupleProfileFromDB(
  data: Tables['couple_profiles']['Row'],
  user1: User,
  user2: User,
): CoupleProfile {
  return {
    id: data.id,
    user1,
    user2,
    relationshipStart: data.relationship_start,
    status: data.status,
    anniversary: data.anniversary || undefined,
    story: data.story || undefined,
    coverImage: data.cover_image || undefined,
    createdAt: data.created_at,
    updatedAt: data.updated_at,
  }
}

function mapMessageFromDB(data: Tables['messages']['Row']): Message {
  return {
    id: data.id,
    content: data.content,
    type: data.type,
    sender: data.sender_id,
    receiver: data.receiver_id,
    isRead: data.is_read,
    createdAt: data.created_at,
  }
}

function mapAnniversaryFromDB(data: Tables['anniversaries']['Row']): Anniversary {
  return {
    id: data.id,
    title: data.title,
    date: data.date,
    type: data.type,
    description: data.description || undefined,
    isRecurring: data.is_recurring,
    reminderDays: data.reminder_days || undefined,
    createdAt: data.created_at,
  }
}

function mapDateRecordFromDB(data: Tables['date_records']['Row']): DateRecord {
  return {
    id: data.id,
    title: data.title,
    date: data.date,
    location: data.location,
    description: data.description || undefined,
    photos: data.photos,
    mood: data.mood as 1 | 2 | 3 | 4 | 5,
    cost: data.cost || undefined,
    weather: data.weather || undefined,
    tags: data.tags,
    createdAt: data.created_at,
  }
}

// 礼物服务
export const giftService = {
  async create(coupleId: string, gift: Omit<Gift, 'id' | 'createdAt'>): Promise<Gift> {
    const { data, error } = await supabase
      .from('gifts')
      .insert({
        couple_id: coupleId,
        title: gift.title,
        description: gift.description || null,
        giver_id: gift.giver,
        receiver_id: gift.receiver,
        occasion: gift.occasion,
        date: gift.date,
        value: gift.value || null,
        photos: gift.photos,
        significance: gift.significance || null,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapGiftFromDB(data)
  },

  async getByCouple(coupleId: string): Promise<Gift[]> {
    const { data, error } = await supabase
      .from('gifts')
      .select('*')
      .eq('couple_id', coupleId)
      .order('date', { ascending: false })

    if (error)
      throw error
    return data.map(mapGiftFromDB)
  },

  async update(id: string, updates: Partial<Gift>): Promise<Gift> {
    const { data, error } = await supabase
      .from('gifts')
      .update({
        title: updates.title,
        description: updates.description || null,
        giver_id: updates.giver,
        receiver_id: updates.receiver,
        occasion: updates.occasion,
        date: updates.date,
        value: updates.value || null,
        photos: updates.photos,
        significance: updates.significance || null,
      })
      .eq('id', id)
      .select()
      .single()

    if (error)
      throw error
    return mapGiftFromDB(data)
  },

  async delete(id: string): Promise<void> {
    const { error } = await supabase
      .from('gifts')
      .delete()
      .eq('id', id)

    if (error)
      throw error
  },
}

// 愿望清单服务
export const wishlistService = {
  async create(coupleId: string, wish: Omit<WishItem, 'id' | 'createdAt' | 'updatedAt'>): Promise<WishItem> {
    const { data, error } = await supabase
      .from('wishlist')
      .insert({
        couple_id: coupleId,
        title: wish.title,
        description: wish.description || null,
        category: wish.category,
        priority: wish.priority,
        status: wish.status,
        target_date: wish.targetDate || null,
        completed_date: wish.completedDate || null,
        photos: wish.photos || null,
        cost: wish.cost || null,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapWishItemFromDB(data)
  },

  async getByCouple(coupleId: string): Promise<WishItem[]> {
    const { data, error } = await supabase
      .from('wishlist')
      .select('*')
      .eq('couple_id', coupleId)
      .order('created_at', { ascending: false })

    if (error)
      throw error
    return data.map(mapWishItemFromDB)
  },

  async update(id: string, updates: Partial<WishItem>): Promise<WishItem> {
    const { data, error } = await supabase
      .from('wishlist')
      .update({
        title: updates.title,
        description: updates.description || null,
        category: updates.category,
        priority: updates.priority,
        status: updates.status,
        target_date: updates.targetDate || null,
        completed_date: updates.completedDate || null,
        photos: updates.photos || null,
        cost: updates.cost || null,
        updated_at: new Date().toISOString(),
      })
      .eq('id', id)
      .select()
      .single()

    if (error)
      throw error
    return mapWishItemFromDB(data)
  },

  async delete(id: string): Promise<void> {
    const { error } = await supabase
      .from('wishlist')
      .delete()
      .eq('id', id)

    if (error)
      throw error
  },
}

// 相册服务
export const albumService = {
  async create(album: Omit<Album, 'id' | 'createdAt' | 'updatedAt' | 'photos'>): Promise<Album> {
    const { data, error } = await supabase
      .from('albums')
      .insert([
        {
          // 某些环境下类型要求可能包含 couple_id，这里保持字段最小化并用数组形式插入
          title: album.title as any,
          description: (album.description || null) as any,
          cover_image: album.coverImage as any,
        } as any,
      ])
      .select()
      .single()

    if (error)
      throw error
    return mapAlbumFromDB(data, [])
  },

  async getAll(): Promise<Album[]> {
    const { data, error } = await supabase
      .from('albums')
      .select(`
        *,
        photos(*)
      `)
      .order('created_at', { ascending: false })

    if (error)
      throw error
    return data.map(album => mapAlbumFromDB(album, album.photos || []))
  },

  async addPhoto(albumId: string, photo: Omit<Photo, 'id' | 'uploadedAt'>): Promise<Photo> {
    const { data, error } = await supabase
      .from('photos')
      .insert({
        album_id: albumId,
        url: photo.url,
        thumbnail: photo.thumbnail || null,
        title: photo.title || null,
        description: photo.description || null,
        location: photo.location || null,
        tags: photo.tags,
        taken_at: photo.takenAt,
      })
      .select()
      .single()

    if (error)
      throw error
    return mapPhotoFromDB(data)
  },

  async removePhoto(photoId: string): Promise<void> {
    const { error } = await supabase
      .from('photos')
      .delete()
      .eq('id', photoId)

    if (error)
      throw error
  },

  async update(albumId: string, updates: Partial<Omit<Album, 'id' | 'createdAt' | 'updatedAt' | 'photos'>>): Promise<Album> {
    const { data, error } = await supabase
      .from('albums')
      .update({
        title: updates.title,
        description: updates.description,
        cover_image: updates.coverImage,
      })
      .eq('id', albumId)
      .select('*, photos(*)')
      .single()

    if (error)
      throw error
    return mapAlbumFromDB(data, data.photos || [])
  },

  async delete(albumId: string): Promise<void> {
    const { error } = await supabase
      .from('albums')
      .delete()
      .eq('id', albumId)

    if (error)
      throw error
  },
}

function mapGiftFromDB(data: Tables['gifts']['Row']): Gift {
  return {
    id: data.id,
    title: data.title,
    description: data.description || undefined,
    giver: data.giver_id,
    receiver: data.receiver_id,
    occasion: data.occasion,
    date: data.date,
    value: data.value || undefined,
    photos: data.photos,
    significance: data.significance || undefined,
    createdAt: data.created_at,
  }
}

function mapWishItemFromDB(data: Tables['wishlist']['Row']): WishItem {
  return {
    id: data.id,
    title: data.title,
    description: data.description || undefined,
    category: data.category,
    priority: data.priority,
    status: data.status,
    targetDate: data.target_date || undefined,
    completedDate: data.completed_date || undefined,
    photos: data.photos || undefined,
    cost: data.cost || undefined,
    createdAt: data.created_at,
    updatedAt: data.updated_at,
  }
}

function mapAlbumFromDB(data: Tables['albums']['Row'], photos: Tables['photos']['Row'][]): Album {
  return {
    id: data.id,
    title: data.title,
    description: data.description || undefined,
    coverImage: data.cover_image,
    photos: photos.map(mapPhotoFromDB),
    createdAt: data.created_at,
    updatedAt: data.updated_at,
  }
}

function mapPhotoFromDB(data: Tables['photos']['Row']): Photo {
  return {
    id: data.id,
    url: data.url,
    thumbnail: data.thumbnail || undefined,
    title: data.title || undefined,
    description: data.description || undefined,
    location: data.location || undefined,
    tags: data.tags,
    takenAt: data.taken_at,
    uploadedAt: data.uploaded_at,
  }
}

export interface MomentDTO {
  id: string
  content: string | null
  images: { url: string, name?: string, size?: number }[] | null
  created_at: string
  user_id: string
  // 可选：如果你在表里有关联用户，记得 select 联表
}

// 朋友圈
function mapMomentFromDB(data: any) {
  return {
    id: data.id,
    content: data.content || '',
    images: data.images || [],
    createTime: data.created_at,
    user: {
      id: data.user_id,
      name: data.user_name || data.user?.name || '', // 若有联表字段
      avatar: data.user_avatar || data.user?.avatar || '', // 若有联表字段
    },
  }
}

export const momentsService = {
  async getByCouple(coupleId: string): Promise<any[]> {
    const { data, error } = await supabase
      .from('moments')
      .select(`
        *,
        user:users!user_id(*)
      `)
      .eq('couple_id', coupleId)
      .order('created_at', { ascending: false })
    if (error)
      throw error
    return (data || []).map(mapMomentFromDB)
  },

  async create(coupleId: string, payload: { userId: string, content: string, images: any[] }) {
    const { data, error } = await supabase
      .from('moments')
      .insert({
        couple_id: coupleId,
        user_id: payload.userId,
        content: payload.content || null,
        images: payload.images || [],
      })
      .select(`
        *,
        user:users!user_id(*)
      `)
      .single()
    if (error)
      throw error
    return mapMomentFromDB(data)
  },

  async update(id: string, updates: { content?: string, images?: any[] }) {
    const { data, error } = await supabase
      .from('moments')
      .update({
        content: updates.content ?? null,
        images: updates.images ?? [],
        updated_at: new Date().toISOString(),
      })
      .eq('id', id)
      .select(`
        *,
        user:users!user_id(*)
      `)
      .single()
    if (error)
      throw error
    return mapMomentFromDB(data)
  },

  async remove(id: string) {
    const { error } = await supabase.from('moments').delete().eq('id', id)
    if (error)
      throw error
  },
}

// 评论
export interface CommentDTO {
  id: string
  moment_id: string
  user_id: string | null
  content: string
  created_at: string
  user?: any
}

export function mapCommentFromDB(c: CommentDTO) {
  return {
    id: c.id,
    momentId: c.moment_id,
    userId: c.user_id || '',
    content: c.content,
    createdAt: c.created_at,
    userName: c.user?.name || '',
    userAvatar: c.user?.avatar || '',
  }
}

export const commentsService = {
  async listByMoment(momentId: string) {
    const { data, error } = await supabase
      .from('comments')
      .select(`*, user:users!user_id(*)`)
      .eq('moment_id', momentId)
      .order('created_at', { ascending: true })
    if (error)
      throw error
    return (data as CommentDTO[]).map(mapCommentFromDB)
  },
  async create(momentId: string, payload: { userId: string, content: string }) {
    const { data, error } = await supabase
      .from('comments')
      .insert({
        moment_id: momentId,
        user_id: payload.userId,
        content: payload.content,
      })
      .select(`*, user:users!user_id(*)`)
      .single()
    if (error)
      throw error
    return mapCommentFromDB(data as CommentDTO)
  },
}
